﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
using System.IO;
using System.Text.RegularExpressions;

using ATMCommonExceptions;
namespace ATMCableCloud
{
	class InputFileParser
	{
		static InputFileParser rInstance_ = null;
		static Mutex mutex_ = new Mutex();
		const string CONNECTION_PATTERN = "^PEER1\\s(.+)\\sPORT\\s(\\d+)\\sPEER2\\s(.+)\\sPORT\\s(\\d+)$";

		InputFileParser()
		{
		}

		/** 
		 * singleton
		 * */
		static public InputFileParser getInstance()
		{
			if (rInstance_ == null)
			{
				mutex_.WaitOne();
				if (rInstance_ == null)
					rInstance_ = new InputFileParser();
			}
			mutex_.ReleaseMutex();
			return rInstance_;
		}

		public void parseFile(string filename)
		{
            try
            {
                string[] lines_with_comments = File.ReadAllLines(filename);
                string[] lines_without_comments = new string[lines_with_comments.Length];
                for (int i = 0; i < lines_without_comments.Length; i++)
                {
                    string[] line = Regex.Split(lines_with_comments[i], ";");
                    lines_without_comments[i] = line[0];
                }
                foreach (string line in lines_without_comments)
                {
                    MatchCollection matches = Regex.Matches(line, CONNECTION_PATTERN);
                    if (matches.Count == 0)
                        throw new SyntaxErrorInFile(line);//blad zlego parsowania
                    foreach (Match match in matches)
                    {
                        GroupCollection link_group = match.Groups;
                        string peer1_name = link_group[1].Value;
                        string peer2_name = link_group[3].Value;
                        int peer1_port = Int32.Parse(link_group[2].Value);
                        int peer2_port = Int32.Parse(link_group[4].Value);
                        Graph.NetworkGraph.getInstance().addNode(peer1_name, peer1_port);
                        Graph.NetworkGraph.getInstance().addNode(peer2_name, peer2_port);
                        Graph.NetworkGraph.getInstance().addLink(peer1_name, peer1_port, peer2_name, peer2_port);
                    }
                }
            }
            catch (SyntaxErrorInFile e)
            {
                Console.WriteLine(e);
                throw;
            }
            catch (FileNotFoundException e)
            {
                Console.WriteLine(e);
                throw;
            }
		}
	}
}
